package com.example.project7

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
import android.media.MediaPlayer
import android.net.Uri
import android.os.Binder
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat

class MusicService : Service() {

	private val binder = MusicBinder()
	private var mediaPlayer: MediaPlayer? = null
	private var playlist: MutableList<Track> = mutableListOf()
	private var currentIndex: Int = 0

	private val channelId = "now_playing_channel"
	private val notifId = 1001

	override fun onCreate() {
		super.onCreate()
		createNotificationChannel()
	}

	override fun onBind(intent: Intent?): IBinder = binder

	override fun onDestroy() {
		super.onDestroy()
		releasePlayer()
	}

	private fun ensurePlayer(): MediaPlayer {
		val existing = mediaPlayer
		if (existing != null) return existing
		val created = MediaPlayer().apply {
			setAudioAttributes(
				AudioAttributes.Builder()
					.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
					.setUsage(AudioAttributes.USAGE_MEDIA)
					.build()
			)
			setOnCompletionListener {
				skipToNext(auto = true)
			}
		}
		mediaPlayer = created
		return created
	}

	private fun releasePlayer() {
		mediaPlayer?.run {
			reset()
			release()
		}
		mediaPlayer = null
	}

	private fun prepareAndPlay(index: Int) {
		if (playlist.isEmpty()) return
		currentIndex = ((index % playlist.size) + playlist.size) % playlist.size
		val track = playlist[currentIndex]
		val player = ensurePlayer()
		player.reset()
		player.setDataSource(applicationContext, track.uri)
		player.prepare()
		player.start()
		startForeground(notifId, buildNowPlayingNotification(track))
	}

	private fun buildNowPlayingNotification(track: Track): Notification {
		val intent = Intent(this, MainActivity::class.java)
		val flags = if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0
		val pendingIntent = PendingIntent.getActivity(this, 0, intent, flags)
		return NotificationCompat.Builder(this, channelId)
			.setContentTitle("正在播放")
			.setContentText(track.title)
			.setSmallIcon(R.mipmap.ic_launcher)
			.setContentIntent(pendingIntent)
			.setOngoing(true)
			.build()
	}

	private fun createNotificationChannel() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
			val channel = NotificationChannel(
				channelId,
				"正在播放",
				NotificationManager.IMPORTANCE_LOW
			)
			val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
			nm.createNotificationChannel(channel)
		}
	}

	private fun skipToNext(auto: Boolean = false) {
		if (playlist.isEmpty()) return
		val nextIndex = (currentIndex + 1) % playlist.size
		prepareAndPlay(nextIndex)
	}

	private fun skipToPrevious() {
		if (playlist.isEmpty()) return
		val prevIndex = if (currentIndex - 1 < 0) playlist.size - 1 else currentIndex - 1
		prepareAndPlay(prevIndex)
	}

	data class Track(
		val uri: Uri,
		val title: String
	)

	inner class MusicBinder : Binder() {
		fun setPlaylist(tracks: List<Track>, startIndex: Int = 0) {
			playlist.clear()
			playlist.addAll(tracks)
			if (tracks.isNotEmpty()) {
				prepareAndPlay(startIndex)
			}
		}
		fun play() {
			val player = ensurePlayer()
			if (!player.isPlaying) {
				player.start()
				if (playlist.isNotEmpty()) {
					startForeground(notifId, buildNowPlayingNotification(playlist[currentIndex]))
				}
			}
		}
		fun pause() {
			mediaPlayer?.let {
				if (it.isPlaying) it.pause()
			}
			// 仍保持前台通知，便于快速恢复播放
		}
		fun stopPlayback() {
			mediaPlayer?.let {
				it.stop()
			}
			stopForeground(STOP_FOREGROUND_DETACH)
		}
		fun next() = skipToNext()
		fun previous() = skipToPrevious()
		fun seekTo(positionMs: Int) {
			mediaPlayer?.seekTo(positionMs)
		}
		fun isPlaying(): Boolean = mediaPlayer?.isPlaying == true
		fun getDuration(): Int = mediaPlayer?.duration ?: 0
		fun getCurrentPosition(): Int = mediaPlayer?.currentPosition ?: 0
		fun getCurrentTitle(): String = playlist.getOrNull(currentIndex)?.title ?: ""
		fun getCurrentIndex(): Int = currentIndex
		fun getPlaylist(): List<Track> = playlist.toList()
	}
}


